# -*- coding: utf-8 -*-
# @Time    : 2021/4/21 9:10
# @Author  : JoSuper
# @File    : doHomeWork.py
# @Software: PyCharm
# @Date    : 2021/4/21
import re
from difflib import SequenceMatcher
from urllib.parse import urlparse, parse_qs

from config import Config
from bs4 import BeautifulSoup


class DoHomeWork(object):

    def __init__(self, config=None):
        self.config = config or Config
        self.answer_url = "https://cs.xnjd.cn/course/exercise/Student_history.action?courseId={}&homeworkId={}"
        self.homework_page = "https://cs.xnjd.cn/course/exercise/Student_doIt.action?courseId={}&homeworkId={}"
        self.audio_answer = {}
        self.judgement_answer = {}
        self.checkbox_answer = {}
        self.finish = False
        self.similar_str = 0.8
        self.similar_str_answer = 0.95
        self.cheched_key = {}

    def similarity(self, a, b):
        tempratio = SequenceMatcher(None, a, b).ratio()
        # print(a, b, tempratio)
        return tempratio > self.similar_str

    def anser_similarity(self, a, b):
        if a[3:] in b[3:]:
            return True
        return False

    def get_audio_value(self, question_info_tag, question_anwser_tag):
        question_info = question_info_tag.text.replace("\xa0", " ").strip().split(" ", 1)[-1].strip()
        answer_info = self.audio_answer.get(question_info, "")
        if answer_info == "":
            for temp in self.audio_answer.keys():
                if self.similarity(temp, question_info):
                    if (temp + question_info) not in self.checkbox_answer.keys():
                        continue
                    self.checkbox_answer[temp + question_info] = True
                    return self.audio_answer[temp]
            return ""
        elif answer_info.startswith("/"):
            img_tag_list = question_anwser_tag.parent.find_all("img")
            for index, img_tag in enumerate(img_tag_list):
                if img_tag.get("src") == answer_info:
                    return index + 1
        answer_list = question_anwser_tag.parent.text.replace("\xa0", "").replace("\t", "").replace("\r", "").strip(
            "\n").split("\n")
        for index, answer in enumerate(answer_list):
            if self.anser_similarity(answer_info, answer):
                return index + 1
        return ""

    def get_checkbox_value(self, question_info_tag, question_tag):
        question_info = question_info_tag.text.replace("\xa0", "").strip().split(".", 1)[-1]
        answer_info = self.checkbox_answer.get(question_info, "") or self.checkbox_answer.get(
            question_info.strip("\r\n"), "")
        if answer_info == "":
            return ""
        table_tag = question_tag.find_parent("table")
        answer_list = list(table_tag.children)[3].text.replace("\xa0", "").replace("\t", "").replace("\r", "").strip(
            "\n").split("\n")
        result_list = []
        for i, answer in enumerate(answer_list):
            for temp in answer_info:
                if temp in answer:
                    input_tag = table_tag.find_all("input")[i]
                    value = input_tag.get("value").split('_')[-1]
                    result_list.append(value)
        return '|'.join(sorted(list(set(result_list))))

    def get_judgement_value(self, question_info_tag, question_tag):
        question_info = question_info_tag.text.replace("\xa0", " ").strip().split(" ", 1)[-1]
        answer_info = self.judgement_answer.get(question_info, "")
        if answer_info == "":
            for temp in self.judgement_answer.keys():
                if self.similarity(temp, question_info):
                    if temp + question_info in self.checkbox_answer.keys():
                        continue
                    self.checkbox_answer[temp + question_info] = True
                    return self.judgement_answer[temp]
        return answer_info

    def parse_audio_answer(self, soup):
        title_list = soup.find_all("td", attrs={"class": "ex_text2"})
        checkbox_td = None
        for title in title_list:
            if "单项选择" in title.text:
                checkbox_td = title
                break
        if checkbox_td is None:
            return
        question_list = checkbox_td.parent.parent.find_all("td", attrs={"align": "left", "class": "ex_text"})
        # question_list = soup.find_all("td", attrs={"align": "left", "class": "ex_text"})
        self.audio_answer.clear()
        for question in question_list:
            # print(question)
            if "你选择的答案" in question.text or "正确答案" in question.text or "解答参考" in question.text:
                continue
            question_table = question.parent.parent
            pattern = re.compile("正确答案")
            answer = list(question_table.find("font", text=pattern).parent.stripped_strings)[-1]
            # new_part = re.compile(f"({answer})")
            real_answer_tag = question_table.find(lambda tag: f"({answer})" in tag.text and tag.name == "td")
            if real_answer_tag is None:
                continue
            real_answer = real_answer_tag.get_text().replace("\xa0", "")
            if real_answer == "":
                img_tag = real_answer_tag.findChild("img")
                if img_tag: real_answer = img_tag.get("src", "")
            question_text = question.text.replace("\xa0", " ").strip().split(" ", 1)[-1]
            if "析构函数" in question_text:
                print(question_text)
            self.audio_answer[question_text.strip()] = real_answer.strip()

    def parse_judgement_answer(self, soup):
        judgement_list = soup.find_all("td", attrs={"class": "stu_homework_list", "align": "left"})
        self.judgement_answer.clear()
        for judgement_td in judgement_list:
            judegment_table = judgement_td.parent.parent
            pattern = re.compile("正确答案")
            anser_td = judegment_table.find("font", text=pattern)
            if anser_td is None:
                continue
            answer = list(anser_td.parent.stripped_strings)[-1]
            print(answer)
            question_text = judgement_td.text.replace("\xa0", "").split(".", 1)[-1]
            self.judgement_answer[question_text.strip()] = 1 if "正确" in answer else 0
        # print(self.judgement_answer)

    def parse_checkbox_answer(self, soup):
        title_list = soup.find_all("td", attrs={"class": "ex_text2"})
        checkbox_td = None
        for title in title_list:
            if "不定项选择" in title.text:
                checkbox_td = title
                break
        if checkbox_td is None:
            return
        question_list = checkbox_td.parent.parent.find_all("td", attrs={"align": "left", "class": "ex_text"})
        self.checkbox_answer.clear()
        for question in question_list:
            font_tat = question.find("font")
            if font_tat is None or font_tat.has_attr("color") and "不选全或者选错，不算完成" not in font_tat.text:
                continue
            question_table = question.parent.parent
            pattern = re.compile("正确答案")
            answer = list(question_table.find("font", text=pattern).parent.stripped_strings)[-1]
            answer_list = answer.strip().split(" ")
            real_answer = []
            for temp in answer_list:
                real_answer_tag = question_table.find(lambda tag: f"({temp})" in tag.text and tag.name == "td")
                if real_answer_tag is None:
                    continue
                real_answer_text = real_answer_tag.get_text().replace("\xa0", " ").strip().split(" ", 1)[-1]
                real_answer.append(real_answer_text)
            question_text = question.text.split(" [", 1)[0].replace("\xa0", "").strip().split(".", 1)[-1]
            self.checkbox_answer[question_text.strip()] = sorted(real_answer)

    def query_answer_info(self, course_id, homework_id):
        url = self.answer_url.format(course_id, homework_id)
        resp = self.config.session.get(url)
        content = resp.text
        # content = self.get_content()
        if "出错啦！你正在做本次作业，在提交之前" in content:
            raise Exception("出错啦！你正在做本次作业!")
        soup = BeautifulSoup(content, "html.parser")
        # print(soup)
        # 处理单选框
        self.parse_audio_answer(soup)
        # 处理判断题
        self.parse_judgement_answer(soup)
        # 处理多选答案
        self.parse_checkbox_answer(soup)

    def get_homework_page(self, course_id, homework_id, is_check=False):
        url = self.homework_page.format(course_id, homework_id)
        resp = self.config.session.get(url)
        content = resp.text
        if "客观题已经全部正确" in content:
            self.finish = True
            return
        soup = BeautifulSoup(content, "html.parser")
        glo_homework_id = soup.find("input", {"id": "glo_homework_id"}).get("value", "")
        glo_allExerciseId = soup.find("input", {"id": "glo_allExerciseId"}).get("value", "")
        glo_allType = soup.find("input", {"id": "glo_allType"}).get("value", "")
        glo_student_id = soup.find("input", {"id": "glo_student_id"}).get("value", "")
        course_url = soup.find("input", {"id": "course_url"}).get("value", "")
        glo_course_code = soup.find("input", {"id": "glo_course_code"}).get("value", "")
        glo_allExerciseId_list = glo_allExerciseId.split("|")
        glo_allType_list = glo_allType.split("|")
        answer_dict = {}
        data = {
            "method": "submithomework",
            "all_ex": glo_allExerciseId,
            "course_code": glo_course_code,
            "homework_id": glo_homework_id,
            "student_id": glo_student_id,
            "all_type": glo_allType,
            "center_code": "",
            "class_code": "",
            "course_url": course_url,
            "qulifyCode": "11",
            "timestamp": "Wed Apr 21 2021 15:08:57 GMT 0800 (中国标准时间)",
            "lefttime": "0|0",
            "repeat_type": "2",
        }
        for index, exercise_id in enumerate(glo_allExerciseId_list):
            answer_key = f"answer_{exercise_id}"
            checkbox_key = f"answer_{exercise_id}_1"
            question_anwser_tag = soup.find("input", attrs={"name": [answer_key, checkbox_key]})
            if question_anwser_tag is None:
                continue
            question_tag = question_anwser_tag.find_parent("table")
            # print(question_tag)
            question_info_tag = question_tag.findChild("td", attrs={"align": "left"})
            question_type = glo_allType_list[index]
            answer_value = ""
            if question_type == "1":
                answer_value = self.get_audio_value(question_info_tag, question_anwser_tag)
            elif question_type == "2":
                if question_info_tag is None:
                    print(question_info_tag)
                answer_value = self.get_checkbox_value(question_info_tag, question_anwser_tag)
            elif question_type == "3":
                answer_value = self.get_judgement_value(question_info_tag, question_anwser_tag)
            if answer_value != "":
                answer_dict[answer_key] = answer_value
        data.update(answer_dict)
        self.post_data(data)
        if is_check: return

        # time.sleep(1)
        if len(glo_allExerciseId_list) == 0:
            self.post_data(data)
            if is_check: return

    def post_data(self, data):
        post_url = "https://cs.xnjd.cn/course/exercise/Ajax_stusavetmp.action?"

        print(data)
        resp = self.config.session.post(post_url, data=data)

    def do_homework(self, course_id, homework_id):
        self.query_answer_info(course_id, homework_id)
        self.finish = False
        while not self.finish:
            self.get_homework_page(course_id, homework_id)
            self.query_answer_info(course_id, homework_id)

    def run(self):
        resp = self.config.session.get("https://study.xnjd.cn/study/Homework_list.action")
        soup = BeautifulSoup(resp.text, "html.parser")
        homework_list = soup.find_all("a", attrs={"target": "blank"})
        for homework_a in homework_list:
            href = homework_a.get("href", "")
            if href == "":
                continue
            info = homework_a.parent.parent.get_text().replace("\n", "").replace("\t", "").replace(" ", "")
            if "客观题0道" in info:
                continue
            paser = urlparse(href)
            params = parse_qs(paser.query)
            course_id = params.get("courseId", [""])[0]
            homework_id = params.get("homeworkId", [""])[0]
            print(course_id, homework_id)
            self.get_homework_page(course_id, homework_id, is_check=True)
            self.do_homework(course_id, homework_id)
